
package com.shiku.imserver.service;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shiku.imserver.common.AbstractService;
import com.shiku.imserver.common.ImConfig;
import com.shiku.imserver.common.message.ChatMessage;
import com.shiku.imserver.common.utils.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class RedisService
        extends AbstractService {
    private static Logger log = LoggerFactory.getLogger(RedisService.class);


    private RedissonClient redissonClient;


    public static final String GET_USERID_BYTOKEN = "loginToken:userId:%s";


    public static final String GET_ACCESS_TOKEN_BY_USER_ID = "loginToken:token:%s";


    public static final String GET_SESSION_BY_ACCESS_TOKEN = "login:%s:session";


    public static final String GET_USER_BY_USERID = "user:%s:data";


    public static final String ROOMJID_LIST = "roomJidList:%s";


    public static final String GET_CONFIG = "app:config";


    public static final String MESSAGE_CHAT = "chatMessage:%s";


    public static final String MESSAGE_GROUP = "groupMessage:%s";


    public RedissonClient getRedissonClient() {

        return this.redissonClient;

    }


    @Override
    public boolean initialize() {

        ImConfig.RedisConfig redisConfig = IMBeanUtils.getImconfig().getRedisConfig();


        log.info("redissonSingle start ");

        try {

            Config config = new Config();

            config.setCodec((Codec) new JsonJacksonCodec());


            SingleServerConfig serverConfig = config.useSingleServer().setAddress(redisConfig.getAddress()).setDatabase(redisConfig.getDatabase());

            serverConfig.setKeepAlive(true);

            serverConfig.setPingConnectionInterval(redisConfig.getPingConnectionInterval());

            serverConfig.setPingTimeout(redisConfig.getPingTimeout());

            serverConfig.setTimeout(redisConfig.getTimeout());

            serverConfig.setConnectTimeout(redisConfig.getConnectTimeout());

            serverConfig.setConnectionMinimumIdleSize(redisConfig.getConnectionMinimumIdleSize());


            serverConfig.setConnectionPoolSize(redisConfig.getConnectionPoolSize());


            if (!StringUtils.isEmpty(redisConfig.getPassword())) {

                serverConfig.setPassword(redisConfig.getPassword());

            }

            this.redissonClient = Redisson.create(config);


            log.info("redissonSingle create end ");


            initConfig();

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

        return true;

    }


    public void initConfig() {

        JSONObject config = getConfig();

        int timeout = config.getIntValue("XMPPTimeout");


        int isSaveMsg = config.getIntValue("isSaveMsg");

        int isSaveMucMsg = config.getIntValue("isSaveMucMsg");

        int isMsgSendTime = config.getIntValue("isMsgSendTime");

        int isKeyWord = config.getIntValue("isKeyWord");

        log.info("initConfig ===> " + config.toJSONString());

        if (0 == timeout) {
            timeout = 180;
        }

        IMBeanUtils.getImconfig().setHeartbeatTimeout(((timeout + 5) * 1000));

        IMBeanUtils.getImconfig().setSaveChatMsg((1 == isSaveMsg));

        IMBeanUtils.getImconfig().setSaveMucMsg((1 == isSaveMucMsg));

        IMBeanUtils.getImconfig().setFilterKeyWord((1 == isKeyWord));


        IMBeanUtils.getBeanManager().getGroupContext().setHeartbeatTimeout(IMBeanUtils.getImconfig().getHeartbeatTimeout());

    }


    public JSONObject getConfig() {

        RBucket<String> bucket = this.redissonClient.getBucket("app:config");

        String config = (String) bucket.get();

        return JSON.parseObject(config);

    }


    public String getAccess_token(long userId) {

        String key = String.format("loginToken:token:%s", new Object[]{Long.valueOf(userId)});

        RBucket<String> bucket = this.redissonClient.getBucket(key);

        return (String) bucket.get();

    }


    public String getUserIdByToken(String token) {

        String key = String.format("loginToken:userId:%s", new Object[]{token});

        RBucket<String> bucket = this.redissonClient.getBucket(key);

        return (String) bucket.get();

    }


    public List<String> queryUserRoomJidList(Integer userId) {

        String key = String.format("roomJidList:%s", new Object[]{userId});

        RList<String> list = this.redissonClient.getList(key);

        if (0 == list.size()) {

            List<String> roomsJidList = IMBeanUtils.getGroupRepository().queryUserRoomsJidList(userId.intValue());

            if (0 < roomsJidList.size()) {

                list.addAllAsync(roomsJidList);

                list.expire(604800L, TimeUnit.SECONDS);

            }

            return roomsJidList;

        }

        return list.readAll();

    }


    public void updateUserRoomJidList(Integer userId) {

        String key = String.format("roomJidList:%s", new Object[]{userId});

        RBucket<Object> bucket = this.redissonClient.getBucket(key);

        List<String> roomsJidList = IMBeanUtils.getGroupRepository().queryUserRoomsJidList(userId.intValue());

        bucket.set(roomsJidList, 604800L, TimeUnit.SECONDS);

    }


    public void deleteUserRoomJidList(Integer userId) {

        String key = String.format("roomJidList:%s", new Object[]{userId});

        RBucket<Object> bucket = this.redissonClient.getBucket(key);

        if (bucket.isExists()) {
            bucket.delete();
        }

    }


    public ChatMessage queryChatMessage(String messageId) {

        String key = String.format("chatMessage:%s", new Object[]{messageId});

        RBucket<ChatMessage> bucket = this.redissonClient.getBucket(key);

        return (ChatMessage) bucket.get();

    }


    public void saveChatMessage(ChatMessage message) {

        String key = String.format("chatMessage:%s", new Object[]{message.getMessageHead().getMessageId()});

        RBucket<ChatMessage> bucket = this.redissonClient.getBucket(key);

        bucket.setAsync(message, 3600L, TimeUnit.SECONDS);

    }


    public ChatMessage queryGroupMessage(String messageId) {

        String key = String.format("groupMessage:%s", new Object[]{messageId});

        RBucket<ChatMessage> bucket = this.redissonClient.getBucket(key);

        return (ChatMessage) bucket.get();

    }


    public void saveGroupMessage(ChatMessage message) {

        String key = String.format("groupMessage:%s", new Object[]{message.getMessageHead().getMessageId()});

        RBucket<ChatMessage> bucket = this.redissonClient.getBucket(key);

        bucket.setAsync(message, 3600L, TimeUnit.SECONDS);

    }

}


